using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;

public class GenTerrain : MonoBehaviour
{
    private delegate void Func(GameObject go);

    public int left { get { return -maxWidth / 2; } }
    public int right { get { return maxWidth / 2; } }
    public int top { get { return maxHeight / 2; } }
    public int bottom { get { return -maxHeight / 2; } }

    [Header("地图大小")]
    [Range(10, 1000)]
    public int maxWidth = 100;
    [Range(10, 1000)]
    public int maxHeight = 50;

    [Range(2, 100)]
    [Tooltip("地图左右两边的海洋宽度")]
    public int borderWidth = 2;
    [Range(2, 100)]
    [Tooltip("地图上下两边的海洋高度")]
    public int borderHeight = 2;

    [Header("地图边界碰撞瓦片")]
    [Tooltip("碰撞瓦片")]
    public TileBase tileFullCollider;

    [Header("地图边界地形瓦片")]
    [Tooltip("海洋瓦片")]
    public TileBase tileSea;
    [Tooltip("海岸瓦片")]
    public TileBase tileSeaCoastWestNorth;
    public TileBase tileSeaCoastNorth;
    public TileBase tileSeaCoastEastNorth;
    public TileBase tileSeaCoastEast;
    public TileBase tileSeaCoastEastSouth;
    public TileBase tileSeaCoastSouth;
    public TileBase tileSeaCoastWestSouth;
    public TileBase tileSeaCoastWest;

    [Header("地图植被瓦片")]
    [Tooltip("草地瓦片")]
    public TileBase[] tileGroundSet;
    [Tooltip("蘑菇瓦片")]
    public TileBase[] tileMushroomSet;
    [Range(0, 100)]
    [Tooltip("蘑菇覆盖率")]
    public float tileMushroomCoverRate = 0.5f;

    [Tooltip("花草瓦片")]
    public TileBase[] tileFlowerSet;
    [Range(0, 100)]
    [Tooltip("花草覆盖率")]
    public float tileFlowerCoverRate = 0.5f;




    private void Awake()
    {
        Dictionary<string, Func> genDict = new Dictionary<string, Func>
        {
            {"植被",(go)=>{ this.GenVegetation(go); } },
            {"地形",(go)=>{ this.GenMapBoundary(go); } },
            {"碰撞",(go)=>{ this.GenMapBoundaryCollider(go); } },
        };

        foreach (string key in genDict.Keys)
        {
            Transform childTransform = transform.Find(key);
            if (childTransform != null)
            {
                Func gen = genDict[key];
                gen(childTransform.gameObject);
            }
        }

        //this.Gen();
    }
    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {

    }

    public void GenVegetation(GameObject tileMapObject)
    {
        Tilemap tileMap = tileMapObject.GetComponent<Tilemap>();
        if (tileMap != null)
        {

            //生成基础草地
            if (tileGroundSet != null && tileGroundSet.Length > 0)
            {
                for (int x = left; x < right; x++)
                {
                    for (int y = top; y > bottom; y--)
                    {
                        this.setTile(tileMap, x, y, tileGroundSet[Random.Range(0, tileGroundSet.Length)]);
                    }
                }
            }
            //生成蘑菇
            if (tileMushroomSet != null && tileMushroomSet.Length > 0)
            {
                int total = maxWidth * maxWidth;
                int fillCount = Mathf.CeilToInt(total * tileMushroomCoverRate / 100);
                for (int i = 0; i < fillCount; i++)
                {
                    int x = Random.Range(-maxWidth / 2, maxWidth / 2);
                    int y = Random.Range(-maxHeight / 2, maxHeight / 2);
                    this.setTile(tileMap, x, y, tileMushroomSet[Random.Range(0, tileMushroomSet.Length)]);
                }
            }
            //生成花草
            if (tileFlowerSet != null && tileFlowerSet.Length > 0)
            {
                int total = maxWidth * maxWidth;
                int fillCount = Mathf.CeilToInt(total * tileFlowerCoverRate / 100);
                for (int i = 0; i < fillCount; i++)
                {
                    int x = Random.Range(-maxWidth / 2, maxWidth / 2);
                    int y = Random.Range(-maxHeight / 2, maxHeight / 2);
                    this.setTile(tileMap, x, y, tileFlowerSet[Random.Range(0, tileFlowerSet.Length)]);
                }
            }

        }
    }

    public void GenMapBoundaryCollider(GameObject tileMapObject)
    {
        Tilemap tileMap = tileMapObject.GetComponent<Tilemap>();
        if (tileMap != null)
        {
            for (int x = left - borderWidth; x < left; x++)
            {
                for (int y = top + borderHeight; y > bottom - borderHeight; y--)
                {
                    this.setTile(tileMap, x, y, tileFullCollider);
                }
            }
            for (int x = left; x < right; x++)
            {
                for (int y = top + borderHeight; y > top; y--)
                {
                    this.setTile(tileMap, x, y, tileFullCollider);
                }
                for (int y = bottom; y > bottom - borderHeight; y--)
                {
                    this.setTile(tileMap, x, y, tileFullCollider);
                }
            }

            for (int x = right; x < right + borderWidth; x++)
            {
                for (int y = top + borderHeight; y > bottom - borderHeight; y--)
                {
                    this.setTile(tileMap, x, y, tileFullCollider);
                }
            }
        }
    }


    public void GenMapBoundary(GameObject tileMapObject)
    {
        Tilemap tileMap = tileMapObject.GetComponent<Tilemap>();
        if (tileMap != null)
        {
            for (int x = left - borderWidth; x < left; x++)
            {
                for (int y = top + borderHeight; y > bottom - borderHeight; y--)
                {
                    this.setTileSea(tileMap, x, y);
                }
            }
            for (int x = left; x < right; x++)
            {
                for (int y = top + borderHeight; y > top; y--)
                {
                    this.setTileSea(tileMap, x, y);
                }
                for (int y = bottom; y > bottom - borderHeight; y--)
                {
                    this.setTileSea(tileMap, x, y);

                }
            }

            for (int x = right; x < right + borderWidth; x++)
            {
                for (int y = top + borderHeight; y > bottom - borderHeight; y--)
                {
                    this.setTileSea(tileMap, x, y);
                }
            }
        }
    }

    private void setTile(Tilemap tileMap, int x, int y, TileBase tile)
    {
        Vector3 v = new Vector3(x, y);
        tileMap.SetTile(Vector3Int.RoundToInt(v), tile);
    }
    private void setTileSea(Tilemap tileMap, int x, int y)
    {
        TileBase tile = tileSea;
        if (y == top + 1 && x >= left && x < right)
        {
            tile = tileSeaCoastNorth;
        }
        else if (x == right && y <= top && y > bottom)
        {
            tile = tileSeaCoastEast;
        }
        else if (y == bottom && x >= left && x < right)
        {
            tile = tileSeaCoastSouth;
        }
        else if (x == left - 1 && y <= top && y > bottom)
        {
            tile = tileSeaCoastWest;
        }
        else if (x == left - 1 && y == top + 1)
        {
            tile = tileSeaCoastWestNorth;
        }
        else if (x == right && y == top + 1)
        {
            tile = tileSeaCoastEastNorth;
        }
        else if (x == right && y == bottom)
        {
            tile = tileSeaCoastEastSouth;
        }
        else if (x == left - 1 && y == bottom)
        {
            tile = tileSeaCoastWestSouth;
        }
        this.setTile(tileMap, x, y, tile);
    }
}
